home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / src / dc1 / genlogic.c < prev    next >
C/C++ Source or Header  |  1997-09-09  |  8KB  |  349 lines

  1. /*
  2.  *    (c)Copyright 1992-1997 Obvious Implementations Corp.  Redistribution and
  3.  *    use is allowed under the terms of the DICE-LICENSE FILE,
  4.  *    DICE-LICENSE.TXT.
  5.  */
  6.  
  7. /*
  8.  *  GENLOGIC.C
  9.  *
  10.  *    logic functions like &, |, etc..
  11.  *
  12.  *  WARNING:    asm_shift must deal with source & dest being different sizes
  13.  *        due to auto-assign
  14.  *
  15.  *  NOTE:  &=, |=, etc.. with lhs bit fields, CreateBinaryResult will
  16.  *       bfext the lhs.  It is expected that the lhs is already freed.
  17.  */
  18.  
  19. #include "defs.h"
  20.  
  21. Prototype void GenAnd(Exp **);
  22. Prototype void GenOr(Exp **);
  23. Prototype void GenXor(Exp **);
  24. Prototype void GenLShf(Exp **);
  25. Prototype void GenRShf(Exp **);
  26. Prototype void GenCompl(Exp **);
  27.  
  28. /*
  29.  *  AND.  We do not have to extend results to an integer:
  30.  *
  31.  *    0 & 0 -> 0
  32.  *    0 & 1 -> 0
  33.  *    1 & 0 -> 0
  34.  *    1 & 1 -> 1
  35.  *
  36.  *  We also optimize for conditionals here.  However, this does not
  37.  *  work for the &= operator so we have to check
  38.  */
  39.  
  40. void
  41. GenAnd(pexp)
  42. Exp **pexp;
  43. {
  44.     Exp *exp = *pexp;
  45.     Exp *e1;
  46.     Exp *e2;
  47.  
  48.     if (exp->ex_Type) {
  49.     if (exp->ex_ExpL->ex_Type == NULL)
  50.         exp->ex_ExpL->ex_Type = exp->ex_Type;
  51.     if (exp->ex_ExpR->ex_Type == NULL)
  52.         exp->ex_ExpR->ex_Type = exp->ex_Type;
  53.     }
  54.  
  55.     CallLeft();
  56.     EnsureReturnStorageLeft();
  57.  
  58.     if (GenPass == 0) {
  59.     if (exp->ex_Flags & EF_ASSEQ) { /*  not req'd. optmizio */
  60.         Type *t = exp->ex_ExpL->ex_Type;
  61.         if (exp->ex_ExpR->ex_Type == NULL)
  62.         exp->ex_ExpR->ex_Type = t;
  63.         exp->ex_Type = t;
  64.     }
  65.     CallRight();
  66.  
  67.     e1 = exp->ex_ExpL;
  68.     e2 = exp->ex_ExpR;
  69.  
  70.     /*
  71.      *  for conditionals, unsignedness can matter.    For example,
  72.      *  char a;  if ((a & 0x80) < 0) ... would not work if we allowed
  73.      *  the return type to be a char.  (the latter example is NEVER
  74.      *  less than 0 since the char is supposed to be extended first.
  75.      *
  76.      *  Do not reduce return size requirements for longs to allow btst
  77.      *  optimization without requiring a move
  78.      */
  79.  
  80.     if (exp->ex_Type == NULL) {
  81.         short isUnsigned = 0;
  82.         if ((e1->ex_Type->Flags | e2->ex_Type->Flags) & TF_UNSIGNED)
  83.         isUnsigned = 1;
  84.  
  85.         if (e1->ex_Stor.st_Type == ST_IntConst) {
  86.         if (exp->ex_Flags & EF_COND) {
  87.             if (e1->ex_Stor.st_IntConst < 0x8000 && e2->ex_Type->Size < 4)
  88.             exp->ex_Type = e2->ex_Type;
  89.             if (e1->ex_Stor.st_IntConst < 0x80 && e2->ex_Type->Size == 1)
  90.             exp->ex_Type = e2->ex_Type;
  91.         }
  92.         }
  93.         if (e2->ex_Stor.st_Type == ST_IntConst) {
  94.         if (exp->ex_Flags & EF_COND) {
  95.             if (e2->ex_Stor.st_IntConst < 0x8000 && e1->ex_Type->Size < 4)
  96.             exp->ex_Type = e1->ex_Type;
  97.             if (e2->ex_Stor.st_IntConst < 0x80 && e1->ex_Type->Size == 1)
  98.             exp->ex_Type = e1->ex_Type;
  99.         }
  100.         }
  101.     }
  102.  
  103.     BinaryLogicRules(exp);
  104.  
  105.     e1 = exp->ex_ExpL;
  106.     e2 = exp->ex_ExpR;
  107.  
  108.     if (e1->ex_Stor.st_Type == ST_IntConst && e2->ex_Stor.st_Type == ST_IntConst) {
  109.         e1->ex_Stor.st_IntConst = e1->ex_Stor.st_IntConst & e2->ex_Stor.st_IntConst;
  110.         *pexp = e1;
  111.     }
  112.     exp->ex_Flags |= (e1->ex_Flags | e2->ex_Flags) & EF_CALL;
  113.     } else {
  114.     CallRight();
  115.     e1 = exp->ex_ExpL;
  116.     e2 = exp->ex_ExpR;
  117.  
  118.     if ((exp->ex_Flags & EF_COND) && !(exp->ex_Flags & EF_ASSEQ)) {
  119.         FreeStorage(&e1->ex_Stor);
  120.         FreeStorage(&e2->ex_Stor);
  121.         exp->ex_Flags |= EF_CONDACK;
  122.         asm_test_and(exp, &e1->ex_Stor, &e2->ex_Stor);
  123.         if (exp->ex_Cond >= 0)
  124.         asm_condbra(COND_NEQ, exp->ex_LabelT);
  125.         else
  126.         asm_condbra(COND_EQ, exp->ex_LabelF);
  127.     } else {
  128.         if (CreateBinaryResultStorage(exp, 1))
  129.         asm_and(exp, &e1->ex_Stor, &e2->ex_Stor, &exp->ex_Stor);
  130.     }
  131.     }
  132. }
  133.  
  134. /*
  135.  *  OR.  We do not have to extend results to an integer:
  136.  *
  137.  *    0 | 0 -> 0
  138.  *    0 | 1 -> 1
  139.  *    1 | 0 -> 1
  140.  *    1 | 1 -> 1
  141.  */
  142.  
  143. void
  144. GenOr(pexp)
  145. Exp **pexp;
  146. {
  147.     Exp *exp = *pexp;
  148.     Exp *e1;
  149.     Exp *e2;
  150.  
  151.     if (exp->ex_Type) {
  152.     if (exp->ex_ExpL->ex_Type == NULL)
  153.         exp->ex_ExpL->ex_Type = exp->ex_Type;
  154.     if (exp->ex_ExpR->ex_Type == NULL)
  155.         exp->ex_ExpR->ex_Type = exp->ex_Type;
  156.     }
  157.     CallLeft();
  158.     EnsureReturnStorageLeft();
  159.  
  160.     if (GenPass == 0) {
  161.     if (exp->ex_Flags & EF_ASSEQ) { /*  not req'd. optmizio */
  162.         Type *t = exp->ex_ExpL->ex_Type;
  163.         if (exp->ex_ExpR->ex_Type == NULL)
  164.         exp->ex_ExpR->ex_Type = t;
  165.         exp->ex_Type = t;
  166.     }
  167.     CallRight();
  168.     BinaryLogicRules(exp);
  169.  
  170.     e1 = exp->ex_ExpL;
  171.     e2 = exp->ex_ExpR;
  172.  
  173.     if (e1->ex_Stor.st_Type == ST_IntConst && e2->ex_Stor.st_Type == ST_IntConst) {
  174.         e1->ex_Stor.st_IntConst = e1->ex_Stor.st_IntConst | e2->ex_Stor.st_IntConst;
  175.         *pexp = e1;
  176.     }
  177.     exp->ex_Flags |= (e1->ex_Flags | e2->ex_Flags) & EF_CALL;
  178.     } else {
  179.     CallRight();
  180.     e1 = exp->ex_ExpL;
  181.     e2 = exp->ex_ExpR;
  182.  
  183.     if (CreateBinaryResultStorage(exp, 1))
  184.         asm_or(exp, &e1->ex_Stor, &e2->ex_Stor, &exp->ex_Stor);
  185.     }
  186. }
  187.  
  188. /*
  189.  *  XOR.  We do not have to extend results to an integer:
  190.  *
  191.  *    0 | 0 -> 0
  192.  *    0 | 1 -> 1
  193.  *    1 | 0 -> 1
  194.  *    1 | 1 -> 0
  195.  */
  196.  
  197. void
  198. GenXor(pexp)
  199. Exp **pexp;
  200. {
  201.     Exp *exp = *pexp;
  202.     Exp *e1;
  203.     Exp *e2;
  204.  
  205.     if (exp->ex_Type) {
  206.     if (exp->ex_ExpL->ex_Type == NULL)
  207.         exp->ex_ExpL->ex_Type = exp->ex_Type;
  208.     if (exp->ex_ExpR->ex_Type == NULL)
  209.         exp->ex_ExpR->ex_Type = exp->ex_Type;
  210.     }
  211.     CallLeft();
  212.     EnsureReturnStorageLeft();
  213.  
  214.     if (GenPass == 0) {
  215.     if (exp->ex_Flags & EF_ASSEQ) { /*  not req'd. optmizio */
  216.         Type *t = exp->ex_ExpL->ex_Type;
  217.         if (exp->ex_ExpR->ex_Type == NULL)
  218.         exp->ex_ExpR->ex_Type = t;
  219.         exp->ex_Type = t;
  220.     }
  221.     CallRight();
  222.     BinaryLogicRules(exp);
  223.  
  224.     e1 = exp->ex_ExpL;
  225.     e2 = exp->ex_ExpR;
  226.  
  227.     if (e1->ex_Stor.st_Type == ST_IntConst && e2->ex_Stor.st_Type == ST_IntConst) {
  228.         e1->ex_Stor.st_IntConst = e1->ex_Stor.st_IntConst ^ e2->ex_Stor.st_IntConst;
  229.         *pexp = e1;
  230.     }
  231.     exp->ex_Flags |= (e1->ex_Flags | e2->ex_Flags) & EF_CALL;
  232.     } else {
  233.     CallRight();
  234.     e1 = exp->ex_ExpL;
  235.     e2 = exp->ex_ExpR;
  236.  
  237.     if (CreateBinaryResultStorage(exp, 1))
  238.         asm_xor(exp, &e1->ex_Stor, &e2->ex_Stor, &exp->ex_Stor);
  239.     }
  240. }
  241.  
  242. void
  243. GenLShf(pexp)
  244. Exp **pexp;
  245. {
  246.     Exp *exp = *pexp;
  247.     Exp *e1;
  248.     Exp *e2;
  249.  
  250.     CallLeft();
  251.     EnsureReturnStorageLeft();
  252.     CallRight();
  253.  
  254.     if (GenPass == 0) {
  255.     ShiftRules(exp);
  256.  
  257.     e1 = exp->ex_ExpL;
  258.     e2 = exp->ex_ExpR;
  259.  
  260.     if (e1->ex_Stor.st_Type == ST_IntConst && e2->ex_Stor.st_Type == ST_IntConst) {
  261.         e1->ex_Stor.st_IntConst = e1->ex_Stor.st_IntConst << e2->ex_Stor.st_IntConst;
  262.         *pexp = e1;
  263.     }
  264.     exp->ex_Flags |= (e1->ex_Flags | e2->ex_Flags) & EF_CALL;
  265.     } else {
  266.     e1 = exp->ex_ExpL;
  267.     e2 = exp->ex_ExpR;
  268.  
  269.     if (CreateBinaryResultStorage(exp, 1))
  270.         asm_shift(exp, -1, &e1->ex_Stor, &e2->ex_Stor, &exp->ex_Stor);
  271.     }
  272. }
  273.  
  274. void
  275. GenRShf(pexp)
  276. Exp **pexp;
  277. {
  278.     Exp *exp = *pexp;
  279.     Exp *e1;
  280.     Exp *e2;
  281.  
  282.     CallLeft();
  283.     EnsureReturnStorageLeft();
  284.     CallRight();
  285.  
  286.     if (GenPass == 0) {
  287.     ShiftRules(exp);
  288.  
  289.     e1 = exp->ex_ExpL;
  290.     e2 = exp->ex_ExpR;
  291.  
  292.     if (e1->ex_Stor.st_Type == ST_IntConst && e2->ex_Stor.st_Type == ST_IntConst) {
  293.         if (e1->ex_Type->Flags & TF_UNSIGNED)
  294.         e1->ex_Stor.st_IntConst = e1->ex_Stor.st_UIntConst >> e2->ex_Stor.st_UIntConst;
  295.         else
  296.         e1->ex_Stor.st_IntConst = e1->ex_Stor.st_IntConst >> e2->ex_Stor.st_IntConst;
  297.         *pexp = e1;
  298.     }
  299.     exp->ex_Flags |= (e1->ex_Flags | e2->ex_Flags) & EF_CALL;
  300.     } else {
  301.     e1 = exp->ex_ExpL;
  302.     e2 = exp->ex_ExpR;
  303.  
  304.     if (CreateBinaryResultStorage(exp, 1))
  305.         asm_shift(exp, 1, &e1->ex_Stor, &e2->ex_Stor, &exp->ex_Stor);
  306.     }
  307. }
  308.  
  309.  
  310. void
  311. GenCompl(pexp)
  312. Exp **pexp;
  313. {
  314.     Exp *exp = *pexp;
  315.     Exp *e1;
  316.  
  317.     if (exp->ex_Type && exp->ex_ExpL->ex_Type == NULL)
  318.     exp->ex_ExpL->ex_Type = exp->ex_Type;
  319.  
  320.     CallLeft();
  321.  
  322.     if (GenPass == 0) {
  323.     UnaryLogicRules(exp);
  324.  
  325.     e1 = exp->ex_ExpL;
  326.  
  327.     if (e1->ex_Stor.st_Type == ST_IntConst) {
  328.         e1->ex_Stor.st_IntConst = ~e1->ex_Stor.st_IntConst;
  329.         *pexp = e1;
  330.     }
  331.     exp->ex_Flags |= e1->ex_Flags & EF_CALL;
  332.     } else {
  333.     Stor con;
  334.  
  335.     e1 = exp->ex_ExpL;
  336.  
  337.     AllocConstStor(&con, -1, exp->ex_Type);
  338.     if (CreateUnaryResultStorage(exp, 1))
  339.         asm_xor(exp, &con, &e1->ex_Stor, &exp->ex_Stor);
  340.     }
  341. }
  342.  
  343. void
  344. filler_gen_logic(void)
  345. {
  346.     Assert(1);
  347. }
  348.  
  349.